package com.party.core.service.crowdfund.impl;

import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.LangUtils;
import com.party.core.dao.read.crowdfund.SupportReadDao;
import com.party.core.dao.write.crowdfund.SupportWriteDao;
import com.party.core.model.BaseModel;
import com.party.core.model.crowdfund.*;
import com.party.core.model.member.Member;
import com.party.core.model.order.OrderStatus;
import com.party.core.service.crowdfund.ISupportService;
import com.sun.istack.NotNull;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 众筹支持服务接口实现
 * Created by wei.li
 *
 * @date 2017/2/16 0016
 * @time 18:53
 */
@Service
public class SupportService implements ISupportService, com.party.core.api.crowdfund.ISupportService {

    @Autowired
    private SupportReadDao supportReadDao;

    @Autowired
    private SupportWriteDao supportWriteDao;

    /**
     * 插入众筹支持
     * @param support 支持信息
     * @return 支持编号
     */
    @Override
    public String insert(Support support) {
        BaseModel.preInsert(support);
        boolean result = supportWriteDao.insert(support);
        if (result){
            return support.getId();
        }
        return null;
    }

    /**
     * 更新众筹支持
     * @param support 支持信息
     * @return 更新结果(true/false)
     */
    @Override
    public boolean update(Support support) {
        return supportWriteDao.update(support);
    }

    /**
     * 逻辑删除众筹支持
     * @param id 实体主键
     * @return 删除结果（true/false）
     */
    @Override
    public boolean deleteLogic(@NotNull String id) {
        if (Strings.isNullOrEmpty(id)){
            return false;
        }
        return supportWriteDao.deleteLogic(id);
    }

    /**
     * 物理删除众筹支持
     * @param id 实体主键
     * @return 删除结果（true/false）
     */
    @Override
    public boolean delete(@NotNull String id) {
        if (Strings.isNullOrEmpty(id)){
            return false;
        }
        return supportWriteDao.delete(id);
    }

    /**
     * 批量逻辑删除众筹支持
     * @param ids 主键集合
     * @return 删除结果(true/false)
     */
    @Override
    public boolean batchDeleteLogic(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)){
            return false;
        }
        return supportWriteDao.batchDeleteLogic(ids);
    }

    /**
     * 批量物理删除众筹支持
     * @param ids 主键集合
     * @return 删除结果(true/false)
     */
    @Override
    public boolean batchDelete(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)){
            return false;
        }
        return supportWriteDao.batchDelete(ids);
    }

    /**
     * 根据编号获取众筹支持
     * @param id 主键
     * @return 众筹支持信息
     */
    @Override
    public Support get(String id) {
        return supportReadDao.get(id);
    }

    /**
     * 分页查询众筹支持
     * @param support 众筹支持
     * @param page 分页信息
     * @return 众筹支持列表
     */
    @Override
    public List<Support> listPage(Support support, Page page) {
        return supportReadDao.listPage(support, page);
    }

    /**
     * 查询所有众筹支付
     * @param support 众筹支持
     * @return 众筹支持列表
     */
    @Override
    public List<Support> list(Support support) {
        return supportReadDao.listPage(support, null);
    }

    /**
     * 批量查询众筹支持
     * @param ids 主键集合
     * @param support 众筹支持
     * @param page 分页信息
     * @return 众筹支持列表
     */
    @Override
    public List<Support> batchList(@NotNull Set<String> ids, Support support, Page page) {
        if (CollectionUtils.isEmpty(ids)){
            return Collections.EMPTY_LIST;
        }
        return supportReadDao.batchList(ids, new HashedMap(), page);
    }

    /**
     * 支持列表（带支持者信息）
     * @param supportWithMember 支持信息
     * @param page 分页参数
     * @return 众筹支持列表
     */
    @Override
    public List<SupportWithMember> listWithMember(SupportWithMember supportWithMember, Page page) {
        return supportReadDao.listWithMember(supportWithMember, page);
    }

    /**
     * 支持列表（带支持者信息和显示商户名称）
     * @param supportWithMember 支持信息
     * @param page 分页参数
     * @return 众筹支持列表
     */
    @Override
    public List<SupportWithMember> listWithMemberAndMerchant(SupportWithMember supportWithMember, Page page) {
        List<SupportWithMember> supportWithMembers = supportReadDao.listWithMemberAndMerchant(supportWithMember, page);
        for (SupportWithMember withMember : supportWithMembers) {
            if (null != withMember.getPayStatus()) {
                withMember.setPayStatusName(SupportStatus.getValue(withMember.getPayStatus()));
            }
        }
        return supportWithMembers;
    }

    /**
     * 支持者带评论
     * @param supportWithMember 支持消息
     * @param page 分页参数
     * @return 支持者列表
     */
    @Override
    public List<SupportWithMember> listWithComment(SupportWithMember supportWithMember, Page page) {
        supportWithMember.setGroupBy(true);
        List<SupportWithMember> supportWithMemberList = supportReadDao.listWithComment(supportWithMember, page);

        List<String> ids = LangUtils.transform(supportWithMemberList, new Function<SupportWithMember, String>() {
            @Override
            public String apply(SupportWithMember supportWithMember) {
                return supportWithMember.getId();
            }
        });
        if (org.apache.commons.collections.CollectionUtils.isEmpty(ids)){
            return Collections.EMPTY_LIST;
        }
        supportWithMember.setGroupBy(false);
        supportWithMember.setIds(Sets.newHashSet(ids));
        return supportReadDao.listWithComment(supportWithMember, null);
    }

    /**
     * 根据订单号查询支持信息
     * @param orderId 订单编号
     * @return 支持信息
     */
    @Override
    public Support findByOrderId(String orderId) {
        return supportReadDao.findByOrderId(orderId);
    }

    /**
     * 根据项目编号查询支持列表
     * @param ids 项目编号集合
     * @return 支持列表
     */
    @Override
    public List<SupportWithMember> findByProjectIds(Set<String> ids) {
        return supportReadDao.list(ids, Maps.newHashMap());
    }

    /**
     * 根据分销关系查询支持列表
     * @param relationId 分销关系
     * @return 支持列表
     */
    @Override
    public List<SupportWithMember> findByRelationId(String relationId) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("relationId", relationId);
        return supportReadDao.list(Sets.newHashSet(), param);
    }

    /**
     * 我支持的金额
     * @param favorerId 支持者编号
     * @param projectId 项目编号
     * @return 支持金额
     */
    @Override
    public Float myFavorerAmount(String favorerId, String projectId) {
        //我支持的金额
        SupportWithMember supportWithMember = new SupportWithMember();
        supportWithMember.setFavorerId(favorerId);
        supportWithMember.setProjectId(projectId);
        supportWithMember.setPayStatus(Constant.IS_SUCCESS);
        Double aDouble = supportReadDao.myFavorerAmount(supportWithMember);
        if (null == aDouble) {
            return 0f;
        }
        Double round = BigDecimalUtils.round(aDouble, 2);
        return round.floatValue();
    }

    /**
     * 根据项目编号查询支持
     * @param projectId 项目编号
     * @return 支持列表
     */
    @Override
    public List<SupportWithMember> findByProjectId(String projectId) {
        SupportWithMember supportWithMember = new SupportWithMember();

        supportWithMember.setStatus(OrderStatus.ORDER_STATUS_HAVE_PAID.getCode());
        supportWithMember.setProjectId(projectId);
        return supportReadDao.listWithMember(supportWithMember, null);
    }

    /**
     * 支持列表
     * @param supportWithMember 支持信息
     * @param page 分页参数
     * @return 支持列表
     */
    @Override
    public List<SupportWithMember> distributorList(SupportWithMember supportWithMember, Page page) {
        return supportReadDao.distributorList(supportWithMember, page);
    }

    /**
     * 众筹支持是否退完
     * @param projectId 项目编号
     * @return 是否
     */
    @Override
    public boolean isRefundAll(String projectId) {
        List<SupportWithMember> supportList = this.findByProjectId(projectId);
        if (CollectionUtils.isEmpty(supportList)){
            return true;
        }
        return false;
    }

    /**
     * payStatus是否全部已经修改
     * @param projectId
     * @return
     */
    public boolean isPayStatusChangeAll(String projectId) {
        SupportWithMember supportWithMember = new SupportWithMember();

        supportWithMember.setPayStatus(Constant.SUPPORT_PAY_STATUS_REFUNDING);
        supportWithMember.setProjectId(projectId);
        List<SupportWithMember> list = supportReadDao.listWithMember(supportWithMember, null);
        if (CollectionUtils.isEmpty(list)){
            return true;
        }
        return false;
    }

    /**
     * 退款失败人数
     * @param projectId
     * @return
     */
    @Override
    public Integer refundAllFailCount(String projectId) {
        SupportWithMember supportWithMember = new SupportWithMember();

        supportWithMember.setPayStatus(Constant.SUPPORT_PAY_STATUS_FAIL);
        supportWithMember.setProjectId(projectId);
        List<SupportWithMember> list = supportReadDao.listWithMember(supportWithMember, null);
        if (null == list) {
            list = Lists.newArrayList();
        }
        return list.size();
    }

    /**
     * 众筹的支持金额
     * @param projectId 众筹编号
     * @return 众筹总额
     */
    @Override
    public Float sumByProjectId(String projectId) {
        Double num = supportReadDao.sumByProjectId(projectId, null);
        return null == num ? 0f : num.floatValue();
    }

    @Override
    public Float sumByProjectId(String projectId, String favorerId) {
        Double num = supportReadDao.sumByProjectId(projectId, favorerId);
        return null == num ? 0f : num.floatValue();
    }

    /**
     * 所有支持
     * @param projectId 项目编号
     * @return 支持列表
     */
    @Override
    public List<Support> findSupportByProjectId(String projectId) {
        Support support = new Support();
        support.setProjectId(projectId);
        return this.list(support);
    }

    /**
     * 统计支持者数据
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param projectId 项目编号
     * @return 统计结果
     */
    @Override
    public List<SupportCount> count(String startTime, String endTime, String projectId) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        param.put("projectId", projectId);
        return supportReadDao.count(param);
    }

    /**
     * 统计支持数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param memberId 会员编号
     * @return 支持数据
     */
    @Override
    public List<SupportCount> countByBuilder(String startTime, String endTime, String memberId) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        param.put("memberId", memberId);
        return supportReadDao.count(param);
    }

    /**
     * 总数
     * @param endTime 结束时间
     * @param projectId 项目编号
     * @return 统计总数
     */
    @Override
    public Double countAll(String endTime, String projectId) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("endTime", endTime);
        param.put("projectId", projectId);
        Double sum = supportReadDao.countAll(param);
        return null == sum ? 0d : sum;
    }

    /**
     * 支持者列表
     * @param memberId 机构编号
     * @return 会员编号
     */
    @Override
    public List<Support> favorerList(String memberId) {
        return supportReadDao.favorerList(memberId);
    }


    /**
     * 支持者带评论
     * @param supportWithMember 支持消息
     * @param page 分页参数
     * @return 支持者列表
     */
    @Override
    public List<SupportWithMember> sponsorListWithComment(SupportWithMember supportWithMember, Page page) {
        supportWithMember.setGroupBy(true);
        return supportReadDao.sponsorListWithComment(supportWithMember, page);
    }

    /**
     * 支持者列表-简略信息
     * @param supportWithMember 支持消息
     * @param page 分页参数
     * @return 支持者列表
     */
    @Override
    public List<SupportWithMember> sponsorListSimple(SupportWithMember supportWithMember, Page page) {
        supportWithMember.setGroupBy(true);
        return supportReadDao.sponsorListSimple(supportWithMember, page);
    }

    @Override
    public List<SupportWithMember> listNew(Support support) {
        return supportReadDao.listNew(support);
    }

    @Override
    public SupportWithMember getLastSupport(Support support) {
        return supportReadDao.getLastSupport(support);
    }

    @Override
    public Date getLastSupportDate(String projectId) {
        return supportReadDao.getLastSupportDate(projectId);
    }

    @Override
    public Integer countByProject(String projectId) {
        Integer count = supportReadDao.countByProject(projectId);
        return count == null ? 0 : count;
    }

    /**
     * 查询某机构下的所有众筹支持者
     * @param partnerId
     * @return
     */
    @Override
    public List<Member> getZcSupportersByPartnerId(String partnerId){
        return supportReadDao.getZcSupportersByPartnerId(partnerId);
    }

    /**
     * 查询某机构某会员的众筹支持金额
     * @return
     */
    public List<Map<String, Object>> getAllGroup(Integer status, String partnerId, String memberId) {
        return supportReadDao.getAllGroup(status, partnerId, memberId);
    }

    @Override
    public List<Map<String, Object>> getAllGroupAPI(Integer status, String partnerId, String memberId) {
        return getAllGroup(status, partnerId, memberId);
    }

    /**
     * 统计目标支持
     * @param targetId 目标编号
     * @param payStatus 支付状态
     * @return 统计数
     */
    @Override
    public Integer countByTargetId(String targetId, Integer... payStatus) {
        return supportReadDao.countByTargetId(targetId, payStatus);
    }

    @Override
    public Map<String, Object> countByProjectDate(String projectId, Date createDate) {
        return supportReadDao.countByProjectDate(projectId, createDate);
    }

    @Override
    public List<ProjectDetailCount> countReviseByProject(String projectId) {
        return supportReadDao.countReviseByProject(projectId);
    }

    @Override
    public void deleteByProjectId(String projectId) {
        supportWriteDao.deleteByProjectId(projectId);
    }

    @Override
    public Float countBySupportDate(String startDate, String endDate, String id) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("startTime", startDate);
        param.put("endTime", endDate);
        param.put("projectId", id);
        Double sum = supportReadDao.countAll(param);
        return null == sum ? 0f : sum.floatValue();
    }

    @Override
    public List<String> getStatusNotMatchSupport(String projectId, Integer orderStatus, Integer payStatus) {
        return supportReadDao.getStatusNotMatchSupport(projectId, orderStatus, payStatus);
    }

    @Override
    public boolean batchUpdate(List<String> supportIds, Integer payStatus) {
        if (CollectionUtils.isEmpty(supportIds)) {
            return false;
        }
        return supportWriteDao.batchUpdate(supportIds, payStatus);
    }

    /**
     * @Author hzq
     * @Description //本次提交退款总人数，除了待支付的，都查出来
     * @Date 9:45 2019/5/20
     * @param support  support
     * @return
     **/
    @Override
    public List<Support> refundSubmitCount(Support support) {
        return supportReadDao.refundSubmitCount(support);
    }

    @Override
    public List<Integer> getStatusByProjectId(String projectId) {
        return supportReadDao.getStatusByProjectId(projectId);
    }

    @Override
    public List<CrowdfundingBattleReport> getSupportBattleReport(String eventId,Integer type) {
        return supportReadDao.getSupportBattleReport(eventId,type);
    }
}
